// https://www.tslang.cn/docs/handbook/advanced-types.html

// 是否为数字的类型断言
function isNumber(x: any): x is number {
  return typeof x === 'number'
}
// 是否为字符串的类型断言
function isString(x: any): x is string {
  return typeof x === 'string'
}

// 以下 padding 的类型就是联合类型，
// 多个类型用 | 分隔，这样我们就可以明确传入的值的类型
function padLeft(value: string, padding: number | string) {
  // 类型守护，防止类型错误
  if (isNumber(padding)) {
    return 'Number' + value
  }
  if (isString(padding)) {
    return 'String' + value
  }

  throw new Error(`Expected string or number, got '${padding}'.`)
}

padLeft('hello', 5)


// ======== 函数类型保存示例 ===========

interface Bird {
  fly(): void;
  layEggs(): void;
}

interface Fish {
  swim(): void;
  layEggs(): void;
}

function isFish(pet: Bird | Fish): pet is Fish {
  return (<Fish>pet).swim !== undefined
}

// 函数的联合类型
function getSmallPet(): Fish | Bird {
  let result: Bird = {
    fly(){ },
    layEggs(){ }
  }
  // ...
  return result
}

let pet = getSmallPet();

if (isFish(pet)) {
  pet.swim();    // errors
} else {
  pet.layEggs(); // okay
}